﻿package core.image.decoder
{
    import core.enum.*;
    import core.image.*;
    import flash.display.*;
    import flash.filters.*;
    import flash.text.*;
    import flash.utils.*;

    public class TUDDecoder extends Object
    {
        var version:int = 0;
        var colormode:int = 0;
        var width:int = 0;
        var height:int = 0;
        var numlayers:int = 0;

        public function TUDDecoder()
        {
            return;
        }// end function

        public function decode(flash.utils:ByteArray, flash.utils:String) : Document
        {
            var _loc_3:ByteArray = null;
            var _loc_5:int = 0;
            flash.utils.uncompress();
            this.ReadHeader(flash.utils);
            var _loc_4:* = new Document(flash.utils, this.width, this.height);
            while (_loc_5 < this.numlayers)
            {
                
                _loc_3 = new ByteArray();
                flash.utils.readBytes(_loc_3, 0, flash.utils.readUnsignedInt());
                _loc_4.AddLayer(this.ReadLayer(_loc_3));
                _loc_5++;
            }
            return _loc_4;
        }// end function

        private function ReadHeader(readUnsignedInt:ByteArray) : void
        {
            this.version = readUnsignedInt.readShort();
            this.colormode = readUnsignedInt.readShort();
            this.width = readUnsignedInt.readInt();
            this.height = readUnsignedInt.readInt();
            this.numlayers = readUnsignedInt.readShort();
            trace("this.numlayers=" + this.numlayers);
            if (this.version == 3)
            {
                readUnsignedInt.readUnsignedInt();
            }
            return;
        }// end function

        private function ReadLayer(ReadLayer:ByteArray) : Layer
        {
            var _loc_2:BitmapData = null;
            var _loc_3:BitmapData = null;
            var _loc_4:ByteArray = null;
            var _loc_5:int = 0;
            var _loc_6:* = new Layer();
            _loc_6.name = ReadLayer.readUTF();
            _loc_6.type = this.IntToLayerType(ReadLayer.readByte());
            _loc_6.x = ReadLayer.readInt();
            _loc_6.y = ReadLayer.readInt();
            var _loc_7:* = ReadLayer.readInt();
            var _loc_8:* = ReadLayer.readInt();
            _loc_6.alpha = ReadLayer.readByte() / 100;
            _loc_6.visible = ReadLayer.readBoolean();
            _loc_6.blendMode = this.IntToBlendMode(ReadLayer.readByte());
            if (this.version > 1)
            {
                _loc_6.alphaLock = ReadLayer.readBoolean();
            }
            _loc_5 = ReadLayer.readUnsignedInt();
            if (_loc_5 > 0)
            {
                _loc_4 = new ByteArray();
                ReadLayer.readBytes(_loc_4, 0, _loc_5);
                _loc_4.position = 0;
                _loc_2 = new BitmapData(_loc_7, _loc_8, true, 16777215);
                _loc_2.setPixels(_loc_2.rect, _loc_4);
            }
            _loc_5 = ReadLayer.readUnsignedInt();
            if (_loc_5 > 0)
            {
                _loc_4 = new ByteArray();
                ReadLayer.readBytes(_loc_4, 0, _loc_5);
                _loc_4.position = 0;
                _loc_3 = new BitmapData(_loc_7, _loc_8, true, 16777215);
                _loc_3.setPixels(_loc_2.rect, _loc_4);
            }
            this.ReadLayerStyle(ReadLayer, _loc_6);
            this.ReadLayerResources(ReadLayer, _loc_6);
            if (_loc_6.type == LayerType.Bitmap || _loc_6.type == LayerType.Text && _loc_6.text == null)
            {
                _loc_6.AddBitmap(_loc_2);
            }
            if (_loc_3 != null)
            {
                _loc_6.AddMask(_loc_3);
            }
            return _loc_6;
        }// end function

        private function ReadLayerStyle(readUnsignedInt:ByteArray, readUnsignedInt:Layer) : void
        {
            var _loc_3:Array = null;
            var _loc_4:int = 0;
            var _loc_5:ByteArray = null;
            var _loc_6:int = 0;
            var _loc_7:* = readUnsignedInt.readByte();
            if (_loc_7 > 0)
            {
                _loc_3 = new Array();
                _loc_4 = 0;
                while (_loc_4 < _loc_7)
                {
                    
                    _loc_5 = new ByteArray();
                    readUnsignedInt.readBytes(_loc_5, 0, readUnsignedInt.readUnsignedInt());
                    _loc_6 = _loc_5.readByte();
                    switch(_loc_6)
                    {
                        case 101:
                        case 102:
                        {
                            this.ReadShadow(_loc_5, _loc_6, _loc_3);
                            break;
                        }
                        case 103:
                        {
                            this.ReadBevel(_loc_5, _loc_3);
                            break;
                        }
                        case 104:
                        case 105:
                        {
                            this.ReadGlow(_loc_5, _loc_6, _loc_3);
                            break;
                        }
                        default:
                        {
                            break;
                        }
                    }
                    _loc_4++;
                }
                readUnsignedInt.filters = _loc_3;
            }
            return;
        }// end function

        private function ReadLayerResources(readUnsignedInt:ByteArray, readUnsignedInt:Layer) : void
        {
            var _loc_3:int = 0;
            var _loc_4:ByteArray = null;
            var _loc_5:int = 0;
            var _loc_6:* = readUnsignedInt.readShort();
            if (_loc_6 > 0)
            {
                _loc_3 = 0;
                while (_loc_3 < _loc_6)
                {
                    
                    _loc_4 = new ByteArray();
                    readUnsignedInt.readBytes(_loc_4, 0, readUnsignedInt.readUnsignedInt());
                    _loc_5 = _loc_4.readByte();
                    switch(_loc_5)
                    {
                        case 101:
                        {
                            this.ReadText(_loc_4, readUnsignedInt);
                            break;
                        }
                        default:
                        {
                            break;
                        }
                    }
                    _loc_3++;
                }
            }
            return;
        }// end function

        private function ReadText(readUnsignedInt:ByteArray, readUnsignedInt:Layer) : void
        {
            var _loc_3:* = new TextFormat();
            var _loc_4:* = readUnsignedInt.readUTF();
            var _loc_5:* = readUnsignedInt.readUTF();
            var _loc_6:* = readUnsignedInt.readShort();
            var _loc_7:* = readUnsignedInt.readUnsignedInt();
            readUnsignedInt.readByte();
            readUnsignedInt.readShort();
            readUnsignedInt.readShort();
            var _loc_8:* = readUnsignedInt.readBoolean();
            var _loc_9:* = readUnsignedInt.readBoolean();
            var _loc_10:* = readUnsignedInt.readBoolean();
            readUnsignedInt.AddText(_loc_5, _loc_6, _loc_7, _loc_8, _loc_9, _loc_4);
            return;
        }// end function

        private function ReadShadow(readUnsignedInt:ByteArray, readUnsignedInt:int, readUnsignedInt:Array) : void
        {
            var _loc_4:* = new DropShadowFilter();
            _loc_4.inner = Boolean(readUnsignedInt != 102);
            _loc_4.alpha = readUnsignedInt.readByte() / 100;
            _loc_4.distance = readUnsignedInt.readShort();
            var _loc_5:* = readUnsignedInt.readByte();
            _loc_4.blurY = readUnsignedInt.readByte();
            _loc_4.blurX = _loc_5;
            _loc_4.angle = readUnsignedInt.readShort();
            _loc_4.color = readUnsignedInt.readUnsignedInt();
            readUnsignedInt.push(_loc_4);
            return;
        }// end function

        private function ReadBevel(readUnsignedInt:ByteArray, readUnsignedInt:Array) : void
        {
            var _loc_3:* = new BevelFilter();
            _loc_3.type = this.IntToBevelStyle(readUnsignedInt.readByte());
            _loc_3.distance = readUnsignedInt.readShort();
            var _loc_4:* = readUnsignedInt.readByte();
            _loc_3.blurY = readUnsignedInt.readByte();
            _loc_3.blurX = _loc_4;
            _loc_3.angle = readUnsignedInt.readShort();
            _loc_3.highlightAlpha = readUnsignedInt.readByte() / 100;
            _loc_3.highlightColor = readUnsignedInt.readUnsignedInt();
            _loc_3.shadowAlpha = readUnsignedInt.readByte() / 100;
            _loc_3.shadowColor = readUnsignedInt.readUnsignedInt();
            readUnsignedInt.push(_loc_3);
            return;
        }// end function

        private function ReadGlow(readUnsignedInt:ByteArray, readUnsignedInt:int, readUnsignedInt:Array) : void
        {
            var _loc_4:* = new GlowFilter();
            _loc_4.inner = Boolean(readUnsignedInt != 105);
            _loc_4.alpha = readUnsignedInt.readByte() / 100;
            _loc_4.strength = readUnsignedInt.readShort();
            var _loc_5:* = readUnsignedInt.readByte();
            _loc_4.blurY = readUnsignedInt.readByte();
            _loc_4.blurX = _loc_5;
            _loc_4.color = readUnsignedInt.readUnsignedInt();
            readUnsignedInt.push(_loc_4);
            return;
        }// end function

        private function IntToBevelStyle(ReadHeader:int) : String
        {
            switch(ReadHeader)
            {
                case 0:
                {
                    return "inner";
                }
                case 1:
                {
                    return "outer";
                }
                case 2:
                {
                    return "full";
                }
                default:
                {
                    return "inner";
                    break;
                }
            }
        }// end function

        private function IntToBlendMode(ReadHeader:int) : String
        {
            switch(ReadHeader)
            {
                case 0:
                {
                    return "normal";
                }
                case 1:
                {
                    return "add";
                }
                case 2:
                {
                    return "alpha";
                }
                case 3:
                {
                    return "darken";
                }
                case 4:
                {
                    return "difference";
                }
                case 5:
                {
                    return "erase";
                }
                case 6:
                {
                    return "hardlight";
                }
                case 7:
                {
                    return "invert";
                }
                case 8:
                {
                    return "layer";
                }
                case 9:
                {
                    return "lighten";
                }
                case 10:
                {
                    return "multiply";
                }
                case 11:
                {
                    return "overlay";
                }
                case 12:
                {
                    return "screen";
                }
                case 13:
                {
                    return "subtract";
                }
                default:
                {
                    return "normal";
                    break;
                }
            }
        }// end function

        private function IntToLayerType(Layer:int) : LayerType
        {
            switch(Layer)
            {
                case 0:
                {
                    return LayerType.Bitmap;
                }
                case 1:
                {
                    return LayerType.Text;
                }
                case 2:
                {
                    return LayerType.Shape;
                }
                default:
                {
                    return LayerType.Bitmap;
                    break;
                }
            }
        }// end function

    }
}
